package cn.magic.user.service.impl;

import cn.magic.basic.constants.BaseConstants;
import cn.magic.basic.dto.SmsCodeDto;
import cn.magic.basic.exception.BusinessException;
import cn.magic.basic.utils.MD5Utils;
import cn.magic.basic.utils.StrUtils;
import cn.magic.user.domain.Logininfo;
import cn.magic.user.domain.User;
import cn.magic.user.mapper.LogininfoMapper;
import cn.magic.user.mapper.UserMapper;
import cn.magic.user.service.IUserService;
import cn.magic.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author pc
 * @since 2022-07-06
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    /**
    * @Title: registerPhone
    * @Description: 根据手机注册实现
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/6 17:44
    * @Parameters: [smsCodeDto]
    * @Return void
    */
    @Override
    public void registerPhone(SmsCodeDto smsCodeDto) {
        String email = smsCodeDto.getEmail();
        // 获取前段传递的电话
        String phone = smsCodeDto.getPhone();
        // 获取Redis中图形验证码的key值
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        // 获取前段传递的用户填写的图形验证码的值
        String phoneCodeValue = smsCodeDto.getPhoneCodeValue();
        // 获取前段传递的二次密码
        String confirmPassword = smsCodeDto.getConfirmPassword();
        // 获取前段传递的密码
        String password = smsCodeDto.getPassword();
/*

        // 1.为空校验
        if (StringUtils.isEmpty(password) && StringUtils.isEmpty(confirmPassword)){
            throw new BusinessException("参数不能为空");
        }

        // 根据电话获取短信验证码的key
        String phoneCodeKey = BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY + phone;
        // 根据key得到value
        Object phoneCodeValueredis = redisTemplate.opsForValue().get(phoneCodeKey);
        // 2.两次手机号是否一致
        if (phoneCodeValueredis == null){
            throw new BusinessException("验证码已失效，请重新获取");
        }
        String phoneCode = phoneCodeValueredis.toString().split(":")[1];
        // 3.判断验证码是否正确
        if (!phoneCode.equalsIgnoreCase(phoneCodeValue)){
            throw new BusinessException("短信验证码输入不正确，请重新输入");
        }
        // 4.两次密码是否一致
        if (!password.equals(confirmPassword)){
            throw new BusinessException("两次密码不一致，请重新输入");
        }
        // 5.判断用户是否已注册，如果已注册提示用户
        User user = userMapper.loadByphone(phone);
        if (user != null){
            throw new BusinessException("用户已经存在，请直接登录");
        }

*/

        // 参数非空判断
       /* if (StringUtils.isEmpty(email) &&
                StringUtils.isEmpty(phone) ||
                StringUtils.isEmpty(phoneCodeValue) ||
                StringUtils.isEmpty(password) ||
                StringUtils.isEmpty(confirmPassword) ||
                !(StringUtils.isEmpty(email) ||
                        StringUtils.isEmpty(phone))) {
            throw new BusinessException("参数不正确！请正确输入");
        }*/
        if (StringUtils.isEmpty(password) && StringUtils.isEmpty(confirmPassword)){
            throw new BusinessException("参数不能为空");
        }
        Object code;
        if (!StringUtils.isEmpty(email)) {
            code = redisTemplate.opsForValue().get(BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY + email);
        } else {
            code = redisTemplate.opsForValue().get(BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY + phone);
        }
        // 判断能否成功获取到短信验证码【验证码失效或者电话号码不一致】
        if (code == null) {
            throw new BusinessException("验证码已失效，请重新输入");
        }
        // 判断短信验证码是否正确
        if (!code.toString().split(":")[1].equals(phoneCodeValue)) {
            throw new BusinessException("验证码错误，请重新输入");
        }
        // 判断两次密码是否一致
        if (!password.equals(confirmPassword)) {
            throw new BusinessException("两次密码不一致，请重新输入");
        }
        // 判断高并发情况下是否被另外注册
        User user;
        if (!StringUtils.isEmpty(email)) {
            // 查询电话号码是否已经注册
            if ((user = userMapper.loadByphone(phone)) != null) {
                throw new BusinessException("该账号已被注册，请直接登录");
            }
        } else if (!StringUtils.isEmpty(phone)) {
            // 查询邮箱是否已经注册
            if ((user = userMapper.loadByEmail(email)) != null) {
                throw new BusinessException("该账号已被注册，请直接登录");
            }
        }



        // 6.初始化user表,就是对你的user对象进行赋值操作
        user = smsCodeDto2User(smsCodeDto);
        // 保存user表
        userMapper.save(user);
        // 保存logininfo
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.save(logininfo);
        // 8.将logininfo主键设置到user表，并修改
        user.setLogininfoId(logininfo.getId());
        userMapper.update(user);


    }

    /** 
    * @Title: smsCodeDto2User
    * @Description: 将smsCodeDto的值赋值给user
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/6 18:23  
    * @Parameters: [smsCodeDto]
    * @Return cn.magic.user.domain.User
    */
    private User smsCodeDto2User(SmsCodeDto smsCodeDto) {
        String phone = smsCodeDto.getPhone();
        String email = smsCodeDto.getEmail();
        User user = new User();
        if (StringUtils.isEmpty(email)){
            user.setUsername(phone);
            user.setPhone(phone);
        } else {
            user.setUsername(email);
            user.setPhone(email);
        }
        String salt = StrUtils.getComplexRandomString(32);
        String saltPassword = MD5Utils.encrypByMd5(salt + smsCodeDto.getPassword());
        user.setPassword(saltPassword);
        user.setSalt(salt);
        return user;
                
    }
    /** 
    * @Title: user2Logininfo
    * @Description: 将user的值赋值给logininfo
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/6 18:28  
    * @Parameters: [user]
    * @Return cn.magic.user.domain.Logininfo
    */
    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setType(1);

        return logininfo;
    }


    /** 
    * @Title: save
    * @Description: 初始化数据以及同步修改关联表
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/9 15:56  
    * @Parameters: [user]
    * @Return void
    */
    @Override
    @Transactional
    public void save(User user) {
        initEmployee(user);
        userMapper.save(user);
        Logininfo logininfo = employee2Logininfo(user);
        logininfoMapper.save(logininfo);
        user.setLogininfoId(logininfo.getId());
        userMapper.update(user);
    }

    /** 
    * @Title: employee2Logininfo
    * @Description: 拷贝employee数据给logininfo
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/9 16:03  
    * @Parameters: [user]
    * @Return cn.magic.user.domain.Logininfo
    */
    private Logininfo employee2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user, logininfo);
        logininfo.setType(0);
        return logininfo;
    }

    /** 
    * @Title: initEmployee
    * @Description: 初始化employee数据
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/9 15:59  
    * @Parameters: [user]
    * @Return void
    */
    private void initEmployee(User user) {
        String salt = StrUtils.getComplexRandomString(32);
        user.setSalt(salt);
        String saltPassword = MD5Utils.encrypByMd5(salt + user.getPassword());
        user.setPassword(saltPassword);

    }

    /** 
    * @Title: remove
    * @Description: 同步删除数据
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/9 16:04  
    * @Parameters: [id]
    * @Return void
    */
    @Override
    public void remove(Long id) {
        // 同步删除数据
        logininfoMapper.remove(userMapper.loadById(id).getLogininfoId());
        super.remove(id);
    }

    /** 
    * @Title: update
    * @Description: 同步修改数据
    * @Author: Mr.pc
    * @Version: 1.0
    * @Date:  2022/7/9 16:05  
    * @Parameters: [user]
    * @Return void
    */
    @Override
    public void update(User user) {
        // 同步修改数据
        Logininfo logininfo = logininfoMapper.loadById(userMapper.loadById(user.getId()).getLogininfoId());
        Long id = logininfo.getId();
        BeanUtils.copyProperties(user, logininfo);
        logininfo.setId(id);
        logininfoMapper.update(logininfo);
        super.update(user);
    }
}
